﻿using System.Windows;
using System.Windows.Controls;
using System;
using System.ComponentModel;
using SuperGo.SilverlightLib;

namespace SuperGo.Silverlight {
	public partial class GameStatus {
		public class DisplayGameStatus : INotifyPropertyChanged {
			public event PropertyChangedEventHandler PropertyChanged;

			public int TurnToDisplay { get; private set; }
			public int BlackCaptures { get; private set; }
			public int WhiteCaptures { get; private set; }
			public bool IsHistoryFirstEnabled { get; private set; }
			public bool IsHistoryPreviousEnabled { get; private set; }
			public bool IsHistoryNextEnabled { get; private set; }
			public bool IsHistoryLastEnabled { get; private set; }
			private GameState _state;
			public string Status { get; private set; }
			public bool LoggedInUserToMove { get; private set; }

			public bool IsDoneMarkingDeadGroupsVisible {
				get {
					return _state == GameState.NegotiatingDeadStones && LoggedInUserToMove;
				}
			}

			public bool IsPassVisible {
				get {
					if (_state == null) return false;
					return _state == GameState.BlackToMove || _state == GameState.WhiteToMove;
				}
			}

			public bool IsResignVisible {
				get {
					if (_state == null) return false;
					return _state == GameState.BlackToMove || _state == GameState.WhiteToMove;
				}
			}

			public bool ArePlayOptionsVisible {
				get {
					return (IsDoneMarkingDeadGroupsVisible || IsPassVisible || IsResignVisible);
				}
			}

			public DisplayGameStatus() {
				TurnToDisplay = 0;
				BlackCaptures = 0;
				WhiteCaptures = 0;
				IsHistoryFirstEnabled = false;
				IsHistoryLastEnabled = false;
				IsHistoryNextEnabled = false;
				IsHistoryPreviousEnabled = false;
				Status = "Initializing";
				LoggedInUserToMove = false;
			}

			public void UpdateStatus(
				int turnToDisplay,
				int currentTurn,
				int blackCaptures,
				int whiteCaptures,
				GameState state,
				bool loggedInPlayerToMove
				) {

				Status = GetStatus(state);
				LoggedInUserToMove = loggedInPlayerToMove;
				_state = state;

				if (PropertyChanged != null) {
					PropertyChanged(this, new PropertyChangedEventArgs("Status"));
					PropertyChanged(this, new PropertyChangedEventArgs("LoggedInUserToMove"));
				}

				UpdateStatus(turnToDisplay, currentTurn, blackCaptures, whiteCaptures);
			}

			public void UpdateStatus(
				int turnToDisplay,
				int currentTurn,
				int blackCaptures,
				int whiteCaptures
				) {

				TurnToDisplay = turnToDisplay;
				BlackCaptures = blackCaptures;
				WhiteCaptures = whiteCaptures;

				IsHistoryFirstEnabled = turnToDisplay != 0;
				IsHistoryPreviousEnabled = turnToDisplay != 0;
				IsHistoryNextEnabled = turnToDisplay < currentTurn;
				IsHistoryLastEnabled = turnToDisplay < currentTurn;

				if (PropertyChanged == null) return;

				PropertyChanged(this, new PropertyChangedEventArgs("TurnToDisplay"));
				PropertyChanged(this, new PropertyChangedEventArgs("BlackCaptures"));
				PropertyChanged(this, new PropertyChangedEventArgs("WhiteCaptures"));
				PropertyChanged(this, new PropertyChangedEventArgs("IsHistoryFirstEnabled"));
				PropertyChanged(this, new PropertyChangedEventArgs("IsHistoryPreviousEnabled"));
				PropertyChanged(this, new PropertyChangedEventArgs("IsHistoryNextEnabled"));
				PropertyChanged(this, new PropertyChangedEventArgs("IsHistoryLastEnabled"));
			}

			private static string GetStatus(GameState state) {
				if (state == null)
					throw new Exception("state can not be null");

				switch (state.Id) {
					case 1:
						return "Black to Move";
					case 2:
						return "White to Move";
					case 3:
						return "Mark Dead Stones";
					case 4:
						return "Black Resigned";
					case 5:
						return "White Resigned";
					case 6:
						return "Game Over";
					default:
						throw new Exception("Unknown GameState: " + state.Name);
				}
			}

		}

		public event EventHandler Pass;
		public event RoutedEventHandler HistoryGoBack;
		public event RoutedEventHandler HistoryGoForward;
		public event RoutedEventHandler HistoryCurrent;
		public event RoutedEventHandler HistoryFirst;
		public event RoutedEventHandler Resign;
		public event RoutedEventHandler DoneMarkingDeadGroups;
		public event RoutedEventHandler Preferences;

		protected readonly DisplayGameStatus _displayGameStatus = new DisplayGameStatus();

		public GameStatus() {
			try {
				InitializeComponent();
				LayoutRoot.Loaded += new RoutedEventHandler(LayoutRoot_Loaded);
			} catch (Exception ex) {
				HandleException(ex);
			}
		}

		void Now_Click(object sender, RoutedEventArgs e) {
			if (HistoryCurrent != null)
				HistoryCurrent(this, null);
		}

		void Next_Click(object sender, RoutedEventArgs e) {
			if (HistoryGoForward != null)
				HistoryGoForward(this, null);
		}

		void Previous_Click(object sender, RoutedEventArgs e) {
			if (HistoryGoBack != null)
				HistoryGoBack(this, null);
		}

		void LayoutRoot_Loaded(object sender, RoutedEventArgs e) {
			try {
				_playOptionsStackPanel = (StackPanel)_playOptions.FindName("_playOptionsStackPanel");

				_activeGames = (Button)_superGo.FindName("_activeGames");
				_activeGames.Click += new RoutedEventHandler(ActiveGames_Click);

				_newGame = (Button)_superGo.FindName("_newGame");
				_newGame.Click += new RoutedEventHandler(NewGame_Click);

				_preferences = (Button) _superGo.FindName("_preferences");
				_preferences.Click += new RoutedEventHandler(preferences_Click);
				
				_pass = (Button)_playOptions.FindName("_pass");
				_pass.Click += new RoutedEventHandler(Pass_Click);

				_resign = (Button)_playOptions.FindName("_resign");
				_resign.Click += new RoutedEventHandler(Resign_Click);

				_historyPrevious = (Button)_historyButtons.FindName("_historyPrevious");
				_historyPrevious.Click += new RoutedEventHandler(Previous_Click);

				_historyNext = (Button)_historyButtons.FindName("_historyNext");
				_historyNext.Click += new RoutedEventHandler(Next_Click);

				_historyLast = (Button)_historyButtons.FindName("_historyLast");
				_historyLast.Click += new RoutedEventHandler(Now_Click);

				_historyFirst = (Button)_historyButtons.FindName("_historyFirst");
				_historyFirst.Click += new RoutedEventHandler(HistoryFirst_Click);

				_doneMarkingDeadGroups = (Button) _playOptions.FindName("_doneMarkingDeadGroups");
				_doneMarkingDeadGroups.Click += new RoutedEventHandler(doneMarkingDeadGroups_Click);

				//LayoutRoot.DataContext = _displayGameStatus;
				_gameStatus.DataContext = _displayGameStatus;
				_historyButtons.DataContext = _displayGameStatus;
				_playOptions.DataContext = _displayGameStatus;
			} catch (Exception ex) {
				HandleException(ex);
			}
		}

		void preferences_Click(object sender, RoutedEventArgs e) {
			if (Preferences != null)
				Preferences(this, new RoutedEventArgs());
		}

		void doneMarkingDeadGroups_Click(object sender, RoutedEventArgs e) {
			Page.ShowDialog("Done?", "Are you sure you're done marking dead stones?", MessageBoxButtons.YesNo, DoneMarkingDeadStonesDialogBoxClosed);
			
			// goto DoneMarkingDeadStonesDialogBoxClosed
		}

		private void DoneMarkingDeadStonesDialogBoxClosed(DialogResult result) {
			if (result == DialogResult.No)
				return;
			
			if (DoneMarkingDeadGroups != null)
				DoneMarkingDeadGroups(this, null);
			
			// goto GamePage._gameStatus_DoneMarkingDeadGroups
		}

		void NewGame_Click(object sender, RoutedEventArgs e) {
			Page.ShowInitiateGame();
		}

		void ActiveGames_Click(object sender, RoutedEventArgs e) {
			Page.ShowContinueExistingGame();
		}

		void HistoryFirst_Click(object sender, RoutedEventArgs e) {
			if (HistoryFirst != null)
				HistoryFirst(this, null);
		}

		void Resign_Click(object sender, RoutedEventArgs e) {
			Page.ShowDialog("Resign?", "Are you sure you wish to resign?", MessageBoxButtons.YesNo, ResignDialogBoxClosed);
		}

		private void ResignDialogBoxClosed(DialogResult result) {
			try {
				if (result == DialogResult.No)
					return;
				if (Resign != null) {
					Resign(this, null);
				}
			} catch (Exception ex) {
				HandleException(ex);
			}
		}

		void Pass_Click(object sender, RoutedEventArgs e) {
			try {
				if (Pass != null) {
					Pass(this, new EventArgs());
				}
			} catch (Exception ex) {
				HandleException(ex);
			}
		}

		public void UpdateStatus(
			int turnToDisplay,
			int currentTurn,
			int blackCaptures,
			int whiteCaptures,
			GameState state,
			bool loggedInPlayerToMove
			) {

			_displayGameStatus.UpdateStatus(turnToDisplay, currentTurn, blackCaptures, whiteCaptures, state, loggedInPlayerToMove);

			_pass.SetVisible(_displayGameStatus.IsPassVisible, _playOptionsStackPanel, _hiddenFields);
			_doneMarkingDeadGroups.SetVisible(_displayGameStatus.IsDoneMarkingDeadGroupsVisible, _playOptionsStackPanel, _hiddenFields);
			_resign.SetVisible(_displayGameStatus.IsResignVisible, _playOptionsStackPanel, _hiddenFields);
		}

		public void UpdateStatus(
			int turnToDisplay,
			int currentTurn,
			int blackCaptures,
			int whiteCaptures
			) {

			_displayGameStatus.UpdateStatus(turnToDisplay, currentTurn, blackCaptures, whiteCaptures);
		}
	}
}
